package com.tengju.user.application.chief;

import com.google.common.collect.Maps;
import com.tengju.user.application.shared.ApplicationException;
import com.tengju.user.application.shared.ApplicationExceptionCode;
import com.tengju.user.domain.model.chief.ChiefGenSecRelation;
import com.tengju.user.domain.model.chief.ChiefGenSecRelationRepository;
import com.tengju.user.domain.model.chief.ChiefId;
import com.tengju.user.domain.model.chief.ChiefSecRelationType;
import com.tengju.user.domain.model.department.DepartmentId;
import com.tengju.user.domain.model.department.DepartmentTree;
import com.tengju.user.domain.model.user.SsoUserId;
import com.tengju.user.domain.model.user.Staff;
import com.tengju.user.domain.model.user.StaffSimpleInfo;
import com.tengju.user.domain.model.user.UserIdCode;
import com.tengju.user.domain.service.DepartmentExternalService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * @author: 李大仙
 * @date: 2021/5/15 2:57 下午
 */
@Slf4j
@Service
@RequiredArgsConstructor(onConstructor_ = {@Autowired})
public class ChiefGenSecRelationService {

    private final ChiefGenSecRelationRepository chiefGenSecRelationRepository;

    private final DepartmentExternalService departmentExternalService;

    @Value("#{${sso.department.leader:}}")
    private Map<Long, Long> departmentLeader;

    @Transactional(rollbackFor = Exception.class)
    public Boolean updateChiefSecRelation(Staff staff, ChiefId chiefId, List<Long> genSecIdCodes) {
        List<UserIdCode> userIdCodes = chiefGenSecRelationRepository.queryGenSecIdCodeList(chiefId);
        if (userIdCodes == null) {
            throw ApplicationException.error(ApplicationExceptionCode.CHIEF_CODE_NOT_EXIST, chiefId);
        }
        if (!departmentExternalService.checkStaffInfo(new SsoUserId(chiefId.getValue()))) {
            throw ApplicationException.error(ApplicationExceptionCode.CHIEF_CODE_NOT_EXIST, chiefId.toString());
        }
        chiefGenSecRelationRepository.batchRemove(chiefId);

        List<ChiefGenSecRelation> collect = genSecIdCodes.stream()
                .map(genSecIdCode -> new ChiefGenSecRelation((chiefId),
                        new UserIdCode(genSecIdCode),
                        staff.getName(), staff.getName()))
                .collect(Collectors.toList());
        chiefGenSecRelationRepository.batchInsert(collect);
        return true;
    }

    public Boolean addChiefSecRelation(Staff staff, ChiefId chiefId, List<Long> genSecIdCodes) {
        List<ChiefGenSecRelation> collect = genSecIdCodes.stream()
                .map(genSecIdCode -> new ChiefGenSecRelation(chiefId,
                        new UserIdCode(genSecIdCode),
                        staff.getName(), staff.getName()))
                .collect(Collectors.toList());
        if (!departmentExternalService.checkStaffInfo(new SsoUserId(chiefId.getValue()))) {
            throw ApplicationException.error(ApplicationExceptionCode.CHIEF_CODE_NOT_EXIST, chiefId.toString());
        }
        // 总监Id在列表中已存在，请移步去进行修改
        checkExistChiefGenSecRelation(chiefId);
        chiefGenSecRelationRepository.batchInsert(collect);
        return true;
    }

    public Boolean removeChiefSecRelation(ChiefId chiefId) {
        int i = chiefGenSecRelationRepository.batchRemove(chiefId);
        if (i == 0) {
            throw ApplicationException.error(ApplicationExceptionCode.CHIEF_CODE_EXIST_FOR_CHIEF_GENSEC_RELATION, chiefId);
        } else {
            return true;
        }
    }

    public void checkExistChiefGenSecRelation(ChiefId chiefId) {
        if (!CollectionUtils.isEmpty(chiefGenSecRelationRepository.queryGenSecIdCodeList(chiefId))) {
            throw ApplicationException.error(ApplicationExceptionCode.CHIEF_CODE_EXIST_FOR_CHIEF_GENSEC_RELATION, chiefId);
        }
    }

    public void updateDepartmentInfos() {
        String departmentLeaderName = "";
        ChiefSecRelationType chiefSecRelationType = ChiefSecRelationType.NORMAL_VIEW;
        if (CollectionUtils.isEmpty(departmentLeader)){
            departmentLeader = Maps.newHashMap();
        }
        List<ChiefId> chiefIdList = chiefGenSecRelationRepository.chiefIdList();
        // 获取部门信息
        List<DepartmentTree> departmentTree = departmentExternalService.getDepartmentTree();
        List<Long> departmentIdList = departmentTree.stream().map(v -> v.getValue().getValue()).collect(Collectors.toList());
        List<StaffSimpleInfo> staffList = departmentExternalService.getStaffSimpleInfosByDepartmentIds(departmentIdList);
        Map<ChiefId, StaffSimpleInfo> chiefIdInfoMap = staffList.stream().distinct().filter(Objects::nonNull)
                .collect(Collectors.toMap(v -> new ChiefId(v.getSsoUserId().getValue()), v1 -> v1, (v2, v3) -> v2));
        // 构建 ChiefSecRelationDTO
        for (ChiefId chief : chiefIdList) {
            if (chiefIdInfoMap.containsKey(chief)) {
                Long departmentId = chiefIdInfoMap.get(chief).getDepartmentId();
                String chiefName = chiefIdInfoMap.get(chief).getRealName();
                String chiefNickname = chiefIdInfoMap.get(chief).getNickname();
                Long departmentLeaderId = departmentLeader.get(departmentId);
                ChiefId leaderId = Optional.ofNullable(departmentLeaderId).map(ChiefId::new).orElse(null);
                if (leaderId != null) {
                    StaffSimpleInfo leaderInfo = departmentExternalService.getStaffSimpleInfoBySsoUserId(new SsoUserId(leaderId.getValue()));
                    departmentLeaderName = Optional.ofNullable(leaderInfo).map(StaffSimpleInfo::getRealName).orElse("");
                    if (!departmentLeader.containsValue(chief.getValue())){
                        chiefSecRelationType = ChiefSecRelationType.DIRECT_MANAGE;
                    } else {
                        chiefSecRelationType = ChiefSecRelationType.NORMAL_VIEW;
                    }
                }
                ChiefGenSecRelation chiefDepartmentRelation = new ChiefGenSecRelation(
                        chief, chiefName, chiefNickname, new DepartmentId(departmentId)
                        , chiefIdInfoMap.get(chief).getDepartmentName()
                        , leaderId, departmentLeaderName, chiefSecRelationType);
                // 批量更新
                chiefGenSecRelationRepository.updateChiefDepartmentRelation(chiefDepartmentRelation);
            }
        }
    }
}
